package com.zn.collection
{
    import com.zn.events.ArrayCollectionEvent;
    
    import flash.utils.Dictionary;

    /**
     *集合对象
     * 可以保存多个对象的Key
     * key必须为字符串
     * @author 朱能
     *
     */
    public class ArrayCollectionDic extends ArrayCollection
    {
        private var _dicKey:Array;

        //key:_dicKeyValue,	value:Dic:_sourceValue
        private var _dic:Dictionary;

        public function ArrayCollectionDic(dicKey:Array = null,source:Array=null)
        {
			super(source);

            //创建字典
            if (!dicKey)
                _dicKey = new Array();
            else
                _dicKey = dicKey.concat();

            createDic();
        }
		
		public override function addAll(addList:Array):void
		{
			var oldValue:Array = source.concat();
			source = source.concat(addList);
			
			for each(var item:Object in addList)
			{
				addDicItem(item);
			}
			
			if(isDispatch)
			{
				var event:ArrayCollectionEvent = new ArrayCollectionEvent(ArrayCollectionEvent.CHANGE, -1, source, oldValue);
				dispatchEvent(event);
			}
			
			updateLength();
		}

		public override function addAllAt(addList:Array, index:int):void
		{
			var oldValue:Array = source.concat();
			source.splice(index, 0, addList);
			
			for each(var item:Object in addList)
			{
				addDicItem(item);
			}
			
			if(isDispatch)
			{
				var event:ArrayCollectionEvent = new ArrayCollectionEvent(ArrayCollectionEvent.CHANGE, -1, source, oldValue);
				dispatchEvent(event);
			}
			
			updateLength();
		}
		
        public override function addItem(item:Object):void
        {
            addItemAt(item, source.length);
        }

        public override function addItemAt(item:Object, index:int):void
        {
			source.splice(index, 0, item);
			
			addDicItem(item);
			
			if(isDispatch)
			{
				var event:ArrayCollectionEvent = new ArrayCollectionEvent(ArrayCollectionEvent.ADD, index, item, null);
				dispatchEvent(event);
			}
			
			updateLength();
        }
		
        public override function removeItemAt(index:int):*
        {
			var list:Array = source.splice(index, 1);
			if(list.length==0)
				return null;
			
			var item:Object=list[0];
			removeDicItem(item);
			
			if(isDispatch)
			{
				var event:ArrayCollectionEvent = new ArrayCollectionEvent(ArrayCollectionEvent.REMOVE, index, item, null);
				dispatchEvent(event);
			}
			
			updateLength();
			
			return item;
        }

        public override function removeAll():void
        {
			var oldArray:ArrayCollection = new ArrayCollection(source.concat());
			source.splice(0, length);
			
			createDic();
			
			if(isDispatch)
			{
				var event:ArrayCollectionEvent = new ArrayCollectionEvent(ArrayCollectionEvent.CHANGE, -1, null, oldArray);
				dispatchEvent(event);
			}
			
			updateLength();
        }

        public override function removeSplice(start:int, length:int):ArrayCollection
        {
			if (length <= 0)
				return null;
			
			var oldArray:ArrayCollection = new ArrayCollection(source.splice(start, length));
			
			for each (var item:Object in oldArray.source)
			{
				removeDicItem(item);
			}
			
			if(isDispatch)
			{
				var event:ArrayCollectionEvent = new ArrayCollectionEvent(ArrayCollectionEvent.CHANGE, -1, null, oldArray);
				dispatchEvent(event);
			}
			
			updateLength();
			
			return oldArray;
        }
		
		public override function setItemAt(item:Object, index:int):*
		{
			var oldValue:Object = source[index];
			
			source.splice(index, 1);
			removeDicItem(oldValue);
			
			source.splice(index, 0, item);
			
			addDicItem(item);
			
			if(isDispatch)
			{
				var event:ArrayCollectionEvent = new ArrayCollectionEvent(ArrayCollectionEvent.REPLACE, index, item, oldValue);
				dispatchEvent(event);
			}
			
			return oldValue;
		}

        /**
         *创建字典 结构
         *
         */
        protected function createDic():void
        {
            _dic = new Dictionary();

            for each (var key:String in _dicKey)
            {
                _dic[key] = new Dictionary();
            }

            //添加字典项
            for each (var item:Object in source)
            {
                addDicItem(item);
            }
        }

        /**
         *新建字典
         *
         */
        public function addDic(key:String):void
        {
            _dic[key] = new Dictionary();
            _dicKey.push(key);

            //添加字典项
            for each (var item:Object in source)
            {
                addDicItemByKey(item, key);
            }
        }

        /**
         *删除字典
         * @param key
         *
         */
        public function removeDic(key:String):void
        {
            delete _dic[key];

            var index:int = _dicKey.indexOf(key);
            if (index != -1)
                _dicKey.splice(index, 1);
        }

        /**
         *构建字典项
         * @param item
         *
         */
        protected function addDicItem(item:Object):void
        {
            for each (var key:String in _dicKey)
            {
                addDicItemByKey(item, key);
            }
        }

        protected function addDicItemByKey(item:Object, key:String):void
        {
            if (item.hasOwnProperty(key))
            {
                var keyValue:Object = item[key];
                _dic[key][keyValue] = item;
            }
        }

        /**
         *移除字典项
         * @param item
         *
         */
        protected function removeDicItem(item:Object):void
        {
            for each (var key:String in _dicKey)
            {
                removeDicItemByKey(item, key);
            }
        }

        protected function removeDicItemByKey(item:Object, key:String):void
        {
            if (item.hasOwnProperty(key))
            {
                var keyValue:Object = item[key];
                delete _dic[key][keyValue];
            }
        }

        /**
         *根据Key得到对象
         * @param key
         * @param value
         * @return
         *
         */
        public function getItemByKey(key:String, value:Object):*
        {
            if (!_dic[key])
                return null;

            return _dic[key][value];
        }

		/**
		 *是否已有 
		 * @param key
		 * @param value
		 * @return 
		 * 
		 */
        public function hasItem(key:String, value:Object):Boolean
        {
            if (getItemByKey(key, value))
                return true;

            return false;
        }
    }
}